package cn.keniykey.mc.landterritory.landview;

import java.util.regex.Pattern;

import javax.annotation.Nullable;

import org.bukkit.Location;
import org.bukkit.OfflinePlayer;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;

import cn.keniykey.mc.generallibrary.input.api.EInputResult;
import cn.keniykey.mc.generallibrary.input.api.IInputRequestManager;
import cn.keniykey.mc.generallibrary.input.api.IInputResultHandler;
import cn.keniykey.mc.landterritory.config.ConfigurationManager;
import cn.keniykey.mc.landterritory.config.LanguageManager;
import cn.keniykey.mc.landterritory.config.ViewsConfiguration;
import cn.keniykey.mc.landterritory.config.ViewsConfiguration.ViewConfig;
import cn.keniykey.mc.landterritory.land.LandRangeToolListener;
import cn.keniykey.mc.landterritory.land.api.LandPoint;
import cn.keniykey.mc.landterritory.land.api.LandRange;
import cn.keniykey.mc.landterritory.toolkit.Util;
import cn.keniykey.mc.viewlibrary.container.api.EContainerType;
import cn.keniykey.mc.viewlibrary.view.api.AbFrameView;
import cn.keniykey.mc.viewlibrary.view.api.IViewClickHandler;
import cn.keniykey.mc.viewlibrary.view.api.ViewClickReport;

public final class LandRangeCreateView extends AbLandFrameView{

	protected LandRangeCreateView(Player player1) {
		super(player1);
	}
	
	private static final String VIEW_NAME = "rangecreate";
	
	private LandRange range;
	
	@Override
	protected void onCreate() {
		super.onCreate();
		final ViewConfig config_view = ViewsConfiguration.getViewConfig(VIEW_NAME);
		this.setViewType(EContainerType.matchContainer(config_view.getViewSize()));
		this.setTitle(Util.conver(config_view.getViewTitle()));
		
		this.range = LandRangeToolListener.getLandRange(this.getPlayer());
		if(this.range != null) this.range = this.range.clone();
		
		this.setIconClick(config_view.getViewItemSlot("back"), config_view.getViewItem("back"), AbLandFrameView.CLICK_BACK);
		this.setIconClick(config_view.getViewItemSlot("size_11"), config_view.getViewItem("size_11"), new IViewClickHandler() {
			@Override
			public void onClick(Player player, AbFrameView view, ViewClickReport report) {
				if(!LandRangeCreateView.this.isMatchClickSpeed()) return;
				LandRangeCreateView.this.createLandRange(10);
			}
		});
		this.setIconClick(config_view.getViewItemSlot("size_21"), config_view.getViewItem("size_21"), new IViewClickHandler() {
			@Override
			public void onClick(Player player, AbFrameView view, ViewClickReport report) {
				if(!LandRangeCreateView.this.isMatchClickSpeed()) return;
				LandRangeCreateView.this.createLandRange(20);
			}
		});
		this.setIconClick(config_view.getViewItemSlot("size_31"), config_view.getViewItem("size_31"), new IViewClickHandler() {
			@Override
			public void onClick(Player player, AbFrameView view, ViewClickReport report) {
				if(!LandRangeCreateView.this.isMatchClickSpeed()) return;
				LandRangeCreateView.this.createLandRange(30);
			}
		});
		this.setIconClick(config_view.getViewItemSlot("size_41"), config_view.getViewItem("size_41"), new IViewClickHandler() {
			@Override
			public void onClick(Player player, AbFrameView view, ViewClickReport report) {
				if(!LandRangeCreateView.this.isMatchClickSpeed()) return;
				LandRangeCreateView.this.createLandRange(40);
			}
		});
		this.setIconClick(config_view.getViewItemSlot("input_x"), config_view.getViewItem("input_x"), new IViewClickHandler() {
			@Override
			public void onClick(Player player, AbFrameView view, ViewClickReport report) {
				if(!LandRangeCreateView.this.isMatchClickSpeed()) return;
				IInputRequestManager.getIInputRequestManager().requestInput(player, "s", ConfigurationManager.View_Choose_Countdown, true, new IInputResultHandler() {
					@Override
					public boolean onInputResult(EInputResult result, OfflinePlayer offplayer, @Nullable String str) {
						boolean cancel = true;
						if(EInputResult.INPUT.equals(result)) {
							cancel = LandRangeCreateView.this.inputCreateLandRange(EXYZ.X, str);
							if(cancel) LandRangeCreateView.this.show();
						}else {
							if(cancel) LandRangeCreateView.this.finishAll();
						}
						LandViewUtil.inputResultResponse(result, offplayer, cancel, 1100100);
						return cancel;
					}
				});
				view.hidden();
				player.sendMessage(LanguageManager.getChatLang(1108102, "s", "X"));
			}
		});
		this.setIconClick(config_view.getViewItemSlot("input_y"), config_view.getViewItem("input_y"), new IViewClickHandler() {
			@Override
			public void onClick(Player player, AbFrameView view, ViewClickReport report) {
				if(!LandRangeCreateView.this.isMatchClickSpeed()) return;
				IInputRequestManager.getIInputRequestManager().requestInput(player, "s", ConfigurationManager.View_Choose_Countdown, true, new IInputResultHandler() {
					@Override
					public boolean onInputResult(EInputResult result, OfflinePlayer offplayer, @Nullable String str) {
						boolean cancel = true;
						if(EInputResult.INPUT.equals(result)) {
							cancel = LandRangeCreateView.this.inputCreateLandRange(EXYZ.Y, str);
							if(cancel) LandRangeCreateView.this.show();
						}else {
							if(cancel) LandRangeCreateView.this.finishAll();
						}
						LandViewUtil.inputResultResponse(result, offplayer, cancel, 1100100);
						return cancel;
					}
				});
				view.hidden();
				player.sendMessage(LanguageManager.getChatLang(1108102, "s", "Y"));
			}
		});
		this.setIconClick(config_view.getViewItemSlot("input_z"), config_view.getViewItem("input_z"), new IViewClickHandler() {
			@Override
			public void onClick(Player player, AbFrameView view, ViewClickReport report) {
				if(!LandRangeCreateView.this.isMatchClickSpeed()) return;
				IInputRequestManager.getIInputRequestManager().requestInput(player, "s", ConfigurationManager.View_Choose_Countdown, true, new IInputResultHandler() {
					@Override
					public boolean onInputResult(EInputResult result, OfflinePlayer offplayer, @Nullable String str) {
						boolean cancel = true;
						if(EInputResult.INPUT.equals(result)) {
							cancel = LandRangeCreateView.this.inputCreateLandRange(EXYZ.Z, str);
							if(cancel) LandRangeCreateView.this.show();
						}else {
							if(cancel) LandRangeCreateView.this.finishAll();
						}
						LandViewUtil.inputResultResponse(result, offplayer, cancel, 1100100);
						return cancel;
					}
				});
				view.hidden();
				player.sendMessage(LanguageManager.getChatLang(1108102, "s", "Z"));
			}
		});
	}
	
	@Override
	protected void onShowBefore() {
		super.onShowBefore();
		this.refreshRangeInfo();
	}
	
	private enum EXYZ {
		X,Y,Z;
	}
	private boolean inputCreateLandRange(EXYZ type, @Nullable String str) {
		final Player player = this.getPlayer();
		if(str == null || !Pattern.matches("^\\d{1,5}$", str)) {
			LandViewUtil.sendInputMustPositiveNumber(player);
			return false;
		}
		final int grid = Integer.valueOf(str);
		if(grid < 2 || ((grid % 2) != 0)) {
			player.sendMessage(LanguageManager.getChatLang(1108101));
			return false;
		}
		final int xyz = (grid/2);
		if(this.range == null) this.range = new LandRange();
		final Location loc = player.getLocation();
		LandPoint point1 = this.range.getLandPointOne();
		if(point1 == null) {
			point1 = new LandPoint(loc);
			this.range.setLandPointOne(point1);
		}
		LandPoint point2 = this.range.getLandPointTwo();
		if(point2 == null) {
			point2 = new LandPoint(loc);
			this.range.setLandPointTwo(point2);
		}
		final String worldname = loc.getWorld().getName();
		switch(type) {
		case X:
			point1.setWorldName(worldname);
			point1.setX((loc.getBlockX() - xyz));
			point2.setX((loc.getBlockX() + xyz));
			break;
		case Y:
			point1.setWorldName(worldname);
			point1.setY((loc.getBlockY() - xyz));
			point2.setY((loc.getBlockY() + xyz));
			break;
		case Z:
			point1.setWorldName(worldname);
			point1.setZ((loc.getBlockZ() - xyz));
			point2.setZ((loc.getBlockZ() + xyz));
			break;
		default:
			return true;
		}
		this.refreshRangeInfo();
		this.refreshRangeConfirm(this.range.isRangeAllow() && LandViewUtil.isHighlyAccordWithWorld(this.range, loc.getWorld(), player));
		return true;
	}
	private void createLandRange(final int grid) {
		final Player player = this.getPlayer();
		final int xyz = (grid/2);
		if(this.range == null) this.range = new LandRange();
		final Location loc = player.getLocation();
		LandPoint point1 = this.range.getLandPointOne();
		if(point1 == null) {
			point1 = new LandPoint(loc.getWorld().getName(), (loc.getBlockX()-xyz), (loc.getBlockY()-xyz), (loc.getBlockZ()-xyz));
			this.range.setLandPointOne(point1);
		}else {
			point1.setWorldName(loc.getWorld().getName());
			point1.setX((loc.getBlockX() - xyz));
			point1.setY((loc.getBlockY() - xyz));
			point1.setZ((loc.getBlockZ() - xyz));
		}
		LandPoint point2 = this.range.getLandPointTwo();
		if(point2 == null) {
			point2 = new LandPoint(loc.getWorld().getName(), (loc.getBlockX()+xyz), (loc.getBlockY()+xyz), (loc.getBlockZ()+xyz));
			this.range.setLandPointTwo(point2);
		}else {
			point2.setWorldName(loc.getWorld().getName());
			point2.setX((loc.getBlockX() + xyz));
			point2.setY((loc.getBlockY() + xyz));
			point2.setZ((loc.getBlockZ() + xyz));
		}
		this.refreshRangeInfo();
		this.refreshRangeConfirm(this.range.isRangeAllow() && LandViewUtil.isHighlyAccordWithWorld(this.range, loc.getWorld(), player));
	}
	private void refreshRangeInfo() {
		final ViewConfig config_view = ViewsConfiguration.getViewConfig(VIEW_NAME);
		final ItemStack item;
		if(this.range == null) {
			item = config_view.getViewItem("about");
		}else {
			final StringBuilder builder = new StringBuilder(LanguageManager.getLang(1006000));
			builder.append("\n").append(LandViewUtil.getLandRangeListStr(this.range));
			item = ViewsConfiguration.setItemMeta(config_view.getViewItem("about"), null, Util.listFromStr(builder.toString()));
		}
		this.setIcon(config_view.getViewItemSlot("about"), item);
	}
	private void refreshRangeConfirm(boolean show) {
		final ViewConfig config_view = ViewsConfiguration.getViewConfig(VIEW_NAME);
		final int slot = config_view.getViewItemSlot("confirm");
		if(show) {
			this.setIconClick(slot, config_view.getViewItem("confirm"), new IViewClickHandler() {
				private final int slot1 = slot;
				@Override
				public void onClick(Player player, AbFrameView view, ViewClickReport report) {
					if(!LandRangeCreateView.this.isMatchClickSpeed()) return;
					LandRangeToolListener.putLandRange(player, LandRangeCreateView.this.range.clone());
					LandRangeCreateView.this.setIconClick(this.slot1, null, null);
				}
			});
			return;
		}
		this.setIconClick(slot, null, null);
	}
}